package com.walle.gatewayserver.service.impl;

import com.alibaba.fastjson.JSON;
import com.walle.gatewayserver.base.CodeContant;
import com.walle.gatewayserver.base.SsoConstant;
import com.walle.gatewayserver.service.ITokenService;
import com.walle.gatewayserver.utils.JWTUtil;
import com.walle.gatewayserver.utils.RedisUtils;
import com.walle.gatewayserver.vo.ApiResult;
import com.walle.gatewayserver.vo.SubjectInfo;
import com.walle.gatewayserver.vo.TokenInfo;
import com.walle.gatewayserver.vo.UserInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class TokenServiceImpl implements ITokenService {

    @Value("${walle.token.iss}")
	private String iss;
    @Value("${walle.token.secret}")
	private String secret;
    @Value("${walle.token.expire.time}")
	private long tokenExpireTime;
	
	@Autowired
    private RedisUtils redisCli;


	@Override
	public ApiResult verifyToken(String uid, String token, String sysType) {
		TokenInfo tokenInfo=null;

		if (StringUtils.isEmpty(token)) {
			// token不正确
			return new ApiResult(CodeContant.TOKEN_ERROR.getCode(), CodeContant.TOKEN_ERROR.getMsg());
		}

		 tokenInfo = getTokenInfoByTokenId(token);

		// token信息是否失效
		if (tokenInfo == null) {

			// token过期
			return new ApiResult(CodeContant.TOKEN_EXPIRED.getCode(), CodeContant.TOKEN_EXPIRED.getMsg());
		}
		redisCli.expire(getTokenKey(token), tokenExpireTime);
		redisCli.expire(getUserTokenKey(tokenInfo.getUser().getUid(),sysType), tokenExpireTime);

        return new ApiResult(CodeContant.SUCCESS.getCode(),CodeContant.SUCCESS.getMsg(), tokenInfo);
	}

	@Override
	public TokenInfo getTokenInfoByTokenId(String token) {
		// TODO Auto-generated method stub
		return (TokenInfo)redisCli.get(getTokenKey(token));
	}

	@Override
	public ApiResult logout(String token, String sysType) {
		ApiResult result = null;

		sysType = sysType.toLowerCase();

        if (!StringUtils.isEmpty(token)) {

            TokenInfo appTokenInfo = getTokenInfoByTokenId(token);

            if (appTokenInfo == null) {

                result = new ApiResult(CodeContant.TOKEN_ERROR.getCode(), CodeContant.TOKEN_ERROR.getMsg());

                return result;
            }

            this.delTokenInfo(token, sysType);
        }

		return new ApiResult(1, "");
	}
	 
	 private void delTokenInfo(String tokenId, String sysType) {

	        // 删除redis中存储token信息，需要设定失效时间
	        redisCli.del(getTokenKey(tokenId));
	    }
	 
	 @Override
	 public TokenInfo createTokenInfo(UserInfo user, String sysType) throws Exception  {

	        TokenInfo tokenInfo = null;

	        sysType = sysType.toLowerCase();
	        try {
	        	
	        	String token = (String) redisCli.get(getUserTokenKey(user.getUid()+"",sysType));

	        	if(!StringUtils.isEmpty(token)) {
	        		redisCli.del(getTokenKey(token));
	        	}

	            // 生成tokenID
	            token = JWTUtil.sign(
	                    iss,
	                    createTokenSub(user),
	                    secret,
	                    tokenExpireTime);
	            // 生成token信息
	            tokenInfo = new TokenInfo(token, user, sysType, (int)tokenExpireTime);
	            // redis中存储token信息，需要设定失效时间
	            redisCli.set(getTokenKey(token), tokenInfo, tokenExpireTime);
	            redisCli.set(getUserTokenKey(user.getUid(),sysType), token, tokenExpireTime);


	        } catch (Exception ex) {
	            throw new Exception( ex.getMessage());
	        } finally {
	        }

	        return tokenInfo;
	    }
	 
	 private String createTokenSub(UserInfo user) {

	        SubjectInfo sub = new SubjectInfo();
	        sub.setUserName(user.getName());
	        return JSON.toJSONString(sub);
	 }
	 public String getTokenKey(String token) {

	        return SsoConstant.TOKEN_INFO + token;
	 }
	 public String getUserTokenKey(String uid,String sysType) {

	        return SsoConstant.USER_TOKEN_KEY+sysType+"_" + uid;
	 }
}
